﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ParanoidMike.CacheMyWork
{
    /// <summary>
    /// This class is used to capture a number of process attributes in a single "structure" (since the use of a Class is preferred over a Structure).
    /// </summary>
    /// <remarks>
    /// The name EnumeratedProcess has been chosen as a way to distinguish from the default process object in the Framework, and is meant to be more generic (and thus more accurately descriptive) than the other choices considered including UserProcess, VisibleProcess or DisplayedProcess.
    /// </remarks>
    class EnumeratedProcess
    {
        // default Constructor
        public EnumeratedProcess()
        {
            // Setting those properties to explicit values whose value at the outset is not indeterminate
            exists = true;
            isHiddenByUser = false;
            isRemovedProgrammatically = false;
            isCacheable = true;
        }

        /// <summary>
        /// Tracks whether the process is still running i.e. if it (a) was detected during initialization, and (b) subsequently exited.
        /// </summary>
        /// <remarks>
        /// Used to enable CacheMyWork to track all hiddenApps, whether they're detected on the system or not.  It is also useful to track any changes of state between startup of CacheMyWork and when one of the lists is displayed to the user.
        /// </remarks>
        private bool exists;
        public bool Exists
        {
            get
            {
                return exists;
            }
            set
            {
                exists = value;

                // When the process is determined to no longer be running, set isCacheable = False so it won't be among the possible choices.
                if (value == false)
                {
                    isCacheable = false;
                }
            }
        }

        /// <summary>
        /// Indicates whether the process has any windows (visible or not).
        /// </summary>
        /// <remarks>
        /// This is an abstraction of the test that checks whether the process.MainWindowHandle = 0.  
        /// Processes whose MainWindowHandle property is non-zero have at least one window.
        /// </remarks>
        private bool hasWindow;
        public bool HasWindow
        {
            get
            {
                return hasWindow;
            }
            set
            {
                hasWindow = value;

                // When the process is determined to have no Window, set isCacheable = False so it won't be among the possible choices.
                if (value == false)
                {
                    isCacheable = false;
                }
            }
        }

        /// <summary>
        /// Indicates whether the process has been "hidden" by the user during the current application session.
        /// </summary>
        /// <remarks>
        /// This will assist the developer in distinguishing between apps hidden via user settings (read in during startup) and apps hidden by use of the Hide Applications dialog.
        /// </remarks>
        private bool isHiddenByUser;
        public bool IsHiddenByUser
        {
            get
            {
                return isHiddenByUser;
            }
            set
            {
                isHiddenByUser = value;

                // When the process is hidden by the user, set isCacheable = False so it won't be among the possible choices.
                if (value == true)
                {
                    isCacheable = false;
                }
            }
        }

        /// <summary>
        /// Indicates whether the process has been removed from the enumeratedProcesses collection by one of the functions in the app operating programmatically.
        /// </summary>
        /// <remarks>
        /// </remarks>
        private bool isRemovedProgrammatically;
        public bool IsRemovedProgrammatically
        {
            get
            {
                return isRemovedProgrammatically;
            }
            set
            {
                isRemovedProgrammatically = value;

                // When the process has been removed, set isCacheable = False so it won't be among the possible choices.
                if (value == true)
                {
                    isCacheable = false;
                }
            }
        }

        //2010-09-04: Commenting out to confirm this causes no harm to our app; delete if nothing crashes due to this within a few days
        //// TODO: this property should become redundant once isCacheable has been fully implemented.
        ///// <summary>
        ///// Summarizes the result of all properties that could be used to "filter out" the processes that aren't of interest to the end user, and shouldn't be presented as a member of the list of cacheable processes" That is, those processes that would be of little or no value to cache for launch at next logon.
        ///// </summary>
        ///// <value></value>
        ///// <returns></returns>
        ///// <remarks>
        ///// This will capture the state of such other properties of this object as IsHiddenByUser and IsRemovedProgrammatically.
        ///// </remarks>
        //private bool _IsProcessVisible
        //{
        //    get
        //    {
        //        if (isRemovedProgrammatically == true || isHiddenByUser == true)
        //        {
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //}
        //public bool IsProcessVisible
        //{
        //    get
        //    {
        //        return _IsProcessVisible;
        //    }
        //}

        /// <summary>
        /// Exposes the result of the P/invoke query to determine if the process' window is visible.
        /// </summary>
        /// <remarks>
        /// This will obviously only be true if the HasWindow property returns True.
        /// </remarks>
        private bool isWindowVisible;
        public bool IsWindowVisible
        {
            get
            {
                return isWindowVisible;
            }
            set
            {
                isWindowVisible = value;

                // When the process is determined to have no visible Window, set isCacheable = False so it won't be among the possible choices.
                // TODO: Re-enable this if we can figure out a better way to determine if the Window is truly visible (not just the Win32 IsWindowVisible property that doesn't work well.
                //If value = False Then
                //    isCacheable = False
                //End If
            }
        }

        /// <summary>
        /// Command line representing how the process can be instantiated.
        /// </summary>
        private string processCommandLine;
        public string ProcessCommandLine
        {
            get
            {
                return processCommandLine;
            }
            set
            {
                processCommandLine = value;
            }
        }

        /// <summary>
        /// Long name of the EnumeratedProcess.
        /// </summary>
        private string processDescriptiveName;
        public string ProcessDescriptiveName
        {
            get
            {
                return processDescriptiveName;
            }
            set
            {
                processDescriptiveName = value;
            }
        }

        /// <summary>
        /// Short name of the EnumeratedProcess.
        /// </summary>
        private string processName;
        public string ProcessName
        {
            get
            {
                return processName;
            }
            set
            {
                processName = value;
            }
        }

        /// <summary>
        /// Represents the Username for the process object.
        /// </summary>
        /// <remarks>
        /// Allows CacheMyWork to determine whether the user context in which the process was launched is the same as the user currently running CacheMyWork.
        /// </remarks>
        private string processOwner;
        public string ProcessOwner
        {
            get
            {
                return processOwner;
            }
            set
            {
                processOwner = value;
            }
        }

        /// <summary>
        /// Returns a read-only aggregation of all other "state" Properties from this class.
        /// </summary>
        /// <remarks>
        /// Sums up all the decisions that have been made about the EnumeratedProcess - this is the "where are we at?" property.
        /// </remarks>
        private bool isCacheable;
        public bool IsCacheable
        {
            get
            {
                return isCacheable;
            }
        }
    }
}
